#include <stdio.h>

// 浮点数的存储（很复杂，只作了解）
// int main()
// {
//     int i = 9;
//     float f = *(float *)&i;
//     printf("int: %d float: %.2f\n\n", i, f);
//
//     f = 9.0;
//     i = *(int *)&f;
//     printf("float: %.2f int: %d\n", f, i);
//     return 0;
// }

// 任何一个二进制浮点数可以表示为 (-1)^S * M * 2^E
// 其中，
// (-1)^S 表示符号位，S==0 为正，S==1 为负
// M 表示有效数字，M>=1 && M<2
// 2^E 表示指数位
// 如 5.0 == 101.0
//        == 1.01 * 2^2
//        == (-1)^0 * 1.01 * 2^2
//
// IEEE 754 规定：
//      对于 32 位浮点数，最高位为 S，接着 8 位为 E，剩下的为 M
//      对于 64 位浮点数，最高位为 S，接着 11 位为 E，剩下的为 M
//
// 因为 M>=1 && M<2，
// 即 M 可以写成 1.xx 的形式（其中 xx 是小数部分），
// 都有整数部分 1，所以规定只保存 xx。
//
// 规定：E 为 unsigned，存储时加上 127（或 1023）
// 取出时三种情况：E 最小；E 最大；E 不是最大也不是最小
// （略）

// 大小端
// 大端存储模式：数据的低位保存在内存的高位，数据的高位保存在内存的低位。
// 小端存储模式：与大端存储相反。
// 本质：字节顺序的不同安排。
// 也可以称为大（小）端字节序存储模式

// 写程序判断当前机器的字节序（提醒：指针指向数据的低地址）
// int check_endian()
// {
//     int a = 1;
//     return *(char *)&a;
// }
// int main()
// {
//     // 使用函数判断当前机器的字节序
//     // 返回1，小端
//     // 返回0，大端
//     int a = check_endian();
//     if (a == 1)
//         printf("small endian\n");
//     else
//         printf("big endian\n");
//     return 0;
// }
// 百度题

// 整数的存储（包含char）
// 整数在内存中以补码的形式存储。
// 正数：原反补相同，
// 负数：~原码（不包括符号位） == 反码，反码 + 1 == 补码

// 内置类型（语言本身就有，如 int,char,double 等）
// 构造类型（数组，结构体，枚举，联合）
// 指针类型
// 空类型 void，通常用于 函数返回类型、函数形参、指针 void* p

// 数据类型
// 意义：
// 1.不同的数据类型开辟的内存空间大小可能不同；
// 2.内存里存的机器码，在不同数据类型下读取结果不同
//   如：1111 1111
//   在 char 类型下是 -1，在 unsigned char 类型下则是 255。
// 3.不同数据类型的底层运算方式可能不同。
//   例如整型和浮点型。
//
// 一句话概括：
// 内存里存的只有也只能是二进制数，
// 数据类型不同，则
// 空间大小可能不同，读取的方式不同，运算的底层实现不同。

// printf 函数的 %
// int main()
// {
//     // a 在内存中的机器码没有变，改变的只是读取方式。
//     char a = 36;
//     printf("%d %c\n", a, a);
//
//     // b 同理。
//     int b = -1;
//     printf("%d %zd\n", b, b);
//     return 0;
// }
// scanf 函数同理。
